home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 019a / opbgd113.zip / IDEMAIN.PAS < prev    next >
Pascal/Delphi Source File  |  1991-10-21  |  28KB  |  1,067 lines

  1. {$A+,F+,O+,R-,S-,V-,X+}
  2.  
  3. unit IDEMain;
  4.  
  5. {$I OPDEFINE.INC}
  6.  
  7. {$IFNDEF UseMouse}
  8.   {$UNDEF UseDrag}
  9. {$ENDIF}
  10.  
  11. interface
  12.  
  13. uses
  14.   DOS,
  15.   OpInline,
  16.   OpRoot,
  17.   OpDos,
  18.   OpString,
  19.   OpCrt,
  20.   OpKey,
  21.   OpCmd,
  22. {$IFDEF UseMouse}
  23.   OpMouse,
  24. {$IFDEF UseDrag}
  25.   OpDrag,
  26. {$ENDIF}
  27. {$ENDIF}
  28.   OpFrame,
  29.   OpWindow,
  30.   OpEdit,
  31.   OpPick,
  32.   OpDir,
  33.   OpBigEd,
  34.   ExecAccess;
  35.  
  36.   {$IFDEF UseMouse}
  37. const
  38.   MouseChar : Char = #04;
  39.   {$ENDIF}
  40.  
  41. procedure Main;
  42.  
  43. implementation
  44.  
  45. const
  46.   BigEditorColorsCfgID : String[19] = 'editor colors array';
  47.   BigEdColors : ColorSet = (
  48.     TextColor       : $1B; TextMono        : $0F;
  49.     CtrlColor       : $1C; CtrlMono        : $0F;
  50.     FrameColor      : $13; FrameMono       : $07;
  51.     HeaderColor     : $20; HeaderMono      : $70;
  52.     ShadowColor     : $08; ShadowMono      : $0F;
  53.     HighlightColor  : $1E; HighlightMono   : $70;
  54.     PromptColor     : $0B; PromptMono      : $07;
  55.     SelPromptColor  : $0E; SelPromptMono   : $07;
  56.     ProPromptColor  : $08; ProPromptMono   : $07;
  57.     FieldColor      : $0B; FieldMono       : $07;
  58.     SelFieldColor   : $0F; SelFieldMono    : $0F;
  59.     ProFieldColor   : $08; ProFieldMono    : $07;
  60.     ScrollBarColor  : $07; ScrollBarMono   : $07;
  61.     SliderColor     : $0F; SliderMono      : $0F;
  62.     HotSpotColor    : $70; HotSpotMono     : $70;
  63.     BlockColor      : $30; BlockMono       : $0F;
  64.     MarkerColor     : $4F; MarkerMono      : $70;
  65.     DelimColor      : $1E; DelimMono       : $0F;
  66.     SelDelimColor   : $70; SelDelimMono    : $0F;
  67.     ProDelimColor   : $1E; ProDelimMono    : $0F;
  68.     SelItemColor    : $3E; SelItemMono     : $70;
  69.     ProItemColor    : $17; ProItemMono     : $07;
  70.     HighItemColor   : $1F; HighItemMono    : $0F;
  71.     AltItemColor    : $1F; AltItemMono     : $0F;
  72.     AltSelItemColor : $3F; AltSelItemMono  : $70;
  73.     FlexAHelpColor  : $1F; FlexAHelpMono   : $0F;
  74.     FlexBHelpColor  : $1F; FlexBHelpMono   : $0F;
  75.     FlexCHelpColor  : $1B; FlexCHelpMono   : $70;
  76.     UnselXrefColor  : $1E; UnselXrefMono   : $09;
  77.     SelXrefColor    : $3F; SelXrefMono     : $70;
  78.     MouseColor      : $4F; MouseMono       : $70
  79.   );
  80.  
  81. const
  82.   BigEditorColorsCfgEnd : Byte = 0;
  83.  
  84. const
  85.   MaxEds = 4;
  86.   SwapFilePath : PathStr = '\$BIGED$.SWP';
  87.   CfgFileName  : PathStr = 'BE3.CFG';
  88.  
  89. const
  90.   PromptLine  = 1;
  91.   StatusLine  = 2;
  92.  
  93.   NormMouse   = $04;
  94.   MoveMouse   = $12;
  95.   ResizeMouse = $1D;
  96.  
  97. type
  98.   CompType = (ctTPC, ctTPCX, ctTPCW, ctTASM, ctTD);
  99.   CompMode = (cmMake, cmBuild, cmErrSrch, cmCustom);
  100.  
  101. const
  102.   CompNames : Array[CompType] of String[4] =
  103.                 ('TPC ', 'TPCX', 'TPCW', 'TASM', 'TDbg');
  104.  
  105. const
  106.   ConfigBanner : String[10] = 'IDE config';
  107.  
  108.     {You will want to adjust these as needed for your system config}
  109.   CompCmds  : Array[CompType] of PathStr =
  110.                 ('C:\TP\TPC.EXE',    {TPC}
  111.                  'C:\TP\TPCX.EXE',   {TPCX}
  112.                  'C:\TPW\TPCW.EXE',  {TPCW}
  113.                  'C:\TP\TASM.EXE',   {TASM}
  114.                  'D:\TD\TD286.EXE'); {TD}
  115.  
  116.   CompDefOpts  : Array[CompType] of PathStr =
  117.                   ('/M /L',          {TPC}
  118.                    '/M /L',          {TPCX}
  119.                    '/M /L',          {TPCW}
  120.                    '',               {TASM}
  121.                    '');              {TD}
  122.  
  123. const
  124.   ConfigEnd : Byte = 0;
  125.  
  126. type
  127.   SpcStateRec =
  128.     record
  129.       SSR : StreamStateRec;
  130.       CT  : CompType;
  131.     end;
  132.  
  133.   FileNodePtr = ^FileNode;
  134.   FileNode =
  135.     Object(DoubleListNode)
  136.       Path : PathStr;
  137.       State : SpcStateRec;
  138.  
  139.       constructor Init(P : PathStr; var S : SpcStateRec);
  140.       destructor Done; virtual;
  141.       procedure Update(P : PathStr; var S : SpcStateRec);
  142.     end;
  143.  
  144. type
  145.   MyBigEditorPtr = ^MyBigEditor;
  146.   MyBigEditor =
  147.     object(BigEditor)
  148.       MainFile : PathStr;
  149.       NFName : PathStr;
  150.       Report : PathStr;
  151.       LC, CC : Integer;
  152.       CompileType : CompType;
  153.       CompileMode : CompMode;
  154.  
  155.       constructor InitCustom(UX, UY, LX, LY : Byte;
  156.                              var Colors : ColorSet;
  157.                              WinOpts : LongInt);
  158.       destructor Done; virtual;
  159.  
  160.       function  FindCompileError : Boolean;
  161.       procedure FindCompileGood;
  162.       procedure CallCompiler(CType : CompType; CMode : CompMode);
  163.       procedure ShowBackground;
  164.       procedure DosShell(Cmd : String);
  165.       procedure ExecuteSelf;
  166.       procedure PerformDosCommand;
  167.       procedure SelectCompiler;
  168.  
  169.       procedure SaveState(var S); virtual;
  170.       procedure RestoreState(var S); virtual;
  171.       procedure ReadFile(FName : string; var FSize : LongInt); virtual;
  172.       procedure SaveFile; virtual;
  173.       procedure NewFilePrompted; virtual;
  174.     end;
  175.  
  176. var
  177.   BE : MyBigEditorPtr;
  178.   TBW : StackWindowPtr;
  179.   FilesList : DoubleList;
  180.  
  181.  
  182.   function HasWildCards(S : PathStr) : Boolean;
  183.   begin
  184.     HasWildCards := (Pos('*',S) > 0) or (Pos('?',S) > 0);
  185.   end;
  186.  
  187.   constructor FileNode.Init(P : PathStr; var S : SpcStateRec);
  188.   begin
  189.     if NOT DoubleListNode.Init then Fail;
  190.     FileNode.Update(P, S);
  191.   end;
  192.  
  193.   destructor FileNode.Done;
  194.   begin
  195.     DoubleListNode.Done;
  196.   end;
  197.  
  198.   procedure FileNode.Update(P : PathStr; var S : SpcStateRec);
  199.   begin
  200.     Path := StUpCase(P);
  201.     State := S;
  202.   end;
  203.  
  204.   procedure FNamePickProc(Item : Word;  Mode : pkMode;
  205.                           var iType : pkItemType;
  206.                           var IString : String;
  207.                           PickPtr : PickListPtr);
  208.   var
  209.     P : FileNodePtr;
  210.   begin
  211.     P := FileNodePtr(FilesList.Nth(Item));
  212.     if P = nil then
  213.       IString := '** None **'
  214.     else
  215.       IString := ' '+P^.Path+' ';
  216.   end;
  217.  
  218.   function WidestFName : Word;
  219.   var
  220.     P : FileNodePtr;
  221.     W : Word;
  222.   begin
  223.     P := FileNodePtr(FilesList.Head);
  224.     W := 0;
  225.     while P <> nil do begin
  226.       if Length(P^.Path) > W then
  227.         W := Length(P^.Path);
  228.       P := FileNodePtr(FilesList.Next(P));
  229.     end;
  230.     WidestFName := W;
  231.   end;
  232.  
  233.   function FindFileInList(PS : PathStr) : FileNodePtr;
  234.   var P : FileNodePtr;
  235.   begin
  236.     PS := StUpCase(PS);
  237.     with FilesList do begin
  238.       P := FileNodePtr(Head);
  239.       while P <> NIL do begin
  240.         if P^.Path = PS then begin
  241.           FindFileInList := P;
  242.           exit;
  243.         end;
  244.         P := FileNodePtr(Next(P));
  245.       end;
  246.       FindFileInList := NIL;
  247.     end;
  248.   end;
  249.  
  250.   procedure AddFileToList(PS : PathStr; var S : SpcStateRec);
  251.   var P : FileNodePtr;
  252.   begin
  253.     P := FindFileInList(PS);
  254.     if P = NIL then begin
  255.       New(P, Init(PS, S));
  256.       FilesList.Append(P);
  257.     end
  258.     else P^.Update(PS, S);
  259.   end;
  260.  
  261. {----------------------------------------------------------------------------}
  262.  
  263.   procedure Status(BEP : BigEditorPtr);
  264.   const
  265.     FN : String[13] = '';
  266.     SL : String[80] =
  267.       {.........1.........2.........3.........4.........5.........6.........7.........8}
  268.       '                Col:      Line:                SAVE Wrap Ins Ind Smart *ZOOM* 1 ';
  269.   var
  270.     S, L : String;
  271.  
  272.     procedure Merge(T : String; Psn : Byte);
  273.     begin
  274.       Move(T[1], S[Psn], Length(T));
  275.     end;
  276.  
  277.     procedure MergeNum(N : LongInt; Psn, PLen : Byte);
  278.     var
  279.       T : String[5];
  280.     begin
  281.       T := Long2Str(N);
  282.       T := Pad(T, PLen);
  283.       Merge(T, Psn);
  284.     end;
  285.  
  286.     procedure MergeNumRight(N : LongInt; Psn, PLen : Byte);
  287.     var
  288.       T : String[5];
  289.     begin
  290.       T := Long2Str(N);
  291.       T := LeftPad(T, PLen);
  292.       Merge(T, Psn-Pred(PLen));
  293.     end;
  294.  
  295.   begin
  296.     with MyBigEditorPtr(BEP)^ do begin
  297.       S := SL;
  298.       if beOptionsAreOn(beNewFile) then begin
  299.         FN := Pad(JustFileName(bePathName), 13);
  300.         beOptionsOff(beNewFile);
  301.       end;
  302.  
  303.       Merge(FN, 4);
  304.  
  305.       L := Long2Str(TNum+LOfs)+'∙'+Long2Str(LList^.Size);
  306.       Merge(L, 33);
  307.  
  308.       MergeNum(CPos+COfs, 22, 4);
  309.       { MergeNumRight(((MemAvail-MemSafetySize) div 1024), 50, 4); }
  310.  
  311.       if not beOptionsAreOn(beModified) then
  312.         Merge('    ', 48);
  313.  
  314.       if not beOptionsAreOn(beWordwrap) then
  315.         Merge('    ', 53);
  316.       if not beOptionsAreOn(beInsert) then
  317.         Merge('Ovr', 58);
  318.       if not beOptionsAreOn(beIndent) then
  319.         Merge('   ', 62);
  320.       if not beOptionsAreOn(beSmartTabs) then
  321.         Merge('Fixed', 66);
  322.       if not IsZoomed then
  323.         Merge('      ',72);
  324.  
  325.       Merge(CompNames[CompileType], 43);
  326.  
  327.       with BigEdColors do
  328.         FastWrite(S, wYL-1, 1, ColorMono(HeaderColor, HeaderMono));
  329.     end;
  330.   end;
  331.  
  332.   procedure UserHook(CPP : CommandProcessorPtr; MT : MatchType; Key : Word);
  333.     {-Called each time CommandProcessor evaluates a keystroke}
  334.   var
  335.     S : string[2];
  336. {$IFDEF UseMouse}
  337.     SaveMouse : Boolean;
  338. {$ENDIF}
  339.   begin
  340.     S := '  ';
  341.     if MT = PartMatch then
  342.       if Lo(Key) < Ord(' ') then begin
  343.         S[1] := '^';
  344.         S[2] := Char(Lo(Key)+$40);
  345.       end
  346.       else
  347.         S[1] := '+';
  348.  
  349. {$IFDEF UseMouse}
  350.     HideMousePrim(SaveMouse);
  351. {$ENDIF}
  352.  
  353.     with BigEdColors do
  354.       FastWrite(S, StatusLine, 1, ColorMono(HeaderColor, HeaderMono));
  355.  
  356. {$IFDEF UseMouse}
  357.     ShowMousePrim(SaveMouse);
  358. {$ENDIF}
  359.   end;
  360.  
  361.   procedure ClearPromptLine;
  362.   begin
  363.     with BigEdColors do
  364.       FastWrite(CharStr(' ', ScreenWidth), PromptLine, 1,
  365.                 ColorMono(PromptColor, PromptMono));
  366.   end;
  367.  
  368.   procedure DisplayMessage(Msg : string);
  369.     {-Display a message at the top of the screen}
  370. {$IFDEF UseMouse}
  371.   var
  372.     SaveMouse : Boolean;
  373. {$ENDIF}
  374.   begin
  375. {$IFDEF UseMouse}
  376.     HideMousePrim(SaveMouse);
  377. {$ENDIF}
  378.  
  379.     ClearPromptLine;
  380.     if Length(Msg) > ScreenWidth then Msg[0] := Chr(ScreenWidth);
  381.     with BigEdColors do
  382.       FastWrite(Msg, PromptLine, 1, ColorMono(PromptColor, PromptMono));
  383.     GotoXYabs(Length(Msg)+1, PromptLine);
  384.  
  385. {$IFDEF UseMouse}
  386.     ShowMousePrim(SaveMouse);
  387. {$ENDIF}
  388.   end;
  389.  
  390.   procedure ErrorProc(UnitCode : Byte; var ErrCode : Word; Msg : string);
  391.     {-Error handler}
  392.   var
  393.     I : Word;
  394.     CursorSL, CursorXY : Word;
  395.   begin
  396.     {save the cursor position and shape}
  397.     GetCursorState(CursorXY, CursorSL);
  398.  
  399.     {clear the status line}
  400.     ClearPromptLine;
  401.  
  402.     {display the error message}
  403.     NormalCursor;
  404.     if Msg = '' then Msg := 'Internal error '+Long2Str(ErrCode);
  405.     DisplayMessage(' '+Msg+'. Press any key...');
  406.  
  407.     {wait for a keypress}
  408.     I := ReadKeyWord;
  409.  
  410.     {clear the prompt line}
  411.     ClearPromptLine;
  412.  
  413.     {Restore cursor position and shape}
  414.     RestoreCursorState(CursorXY, CursorSL);
  415.   end;
  416.  
  417.   function EditFunc(MsgCode : Word;
  418.                     Prompt : string;
  419.                     ForceUp : Boolean;
  420.                     TrimBlanks : Boolean;
  421.                     MaxLen : Byte;
  422.                     var S : string) : Boolean;
  423.    {-Line editing routine}
  424.   var
  425.     LE : LineEditor;
  426.     eWidth : Byte;
  427.   begin
  428.     with LE do begin
  429.       Init(BigEdColors);
  430.       if ForceUp then
  431.         leEditOptionsOn(leForceUpper)
  432.       else
  433.         leEditOptionsOff(leForceUpper);
  434.       if TrimBlanks then
  435.         leEditOptionsOn(leTrimBlanks)
  436.       else
  437.         leEditOptionsOff(leTrimBlanks);
  438.       Prompt := Prompt+' ';
  439.       if Length(Prompt)+MaxLen > ScreenWidth then
  440.         eWidth := ScreenWidth-Length(Prompt)
  441.       else
  442.         eWidth := MaxLen;
  443.       ClearPromptLine;
  444.       ReadString(Prompt, PromptLine, 1, MaxLen, eWidth, S);
  445.       EditFunc := (GetLastCommand <> ccQuit);
  446.       ClearPromptLine;
  447.     end;
  448.   end;
  449.  
  450.   function YesNoFunc(MsgCode : Word; Prompt : string;
  451.                      Default : Byte; QuitAndAll : Boolean) : Byte;
  452.     {-Get a response to a yes-no question}
  453.   var
  454.     LE : LineEditor;
  455.     Ch : Char;
  456.     CharsToTake : CharSet;
  457.   begin
  458.     with LE do begin
  459.       ClearPromptLine;
  460.       Init(BigEdColors);
  461.       leEditOptionsOn(leAllowEscape+leDefaultAccepted+leForceUpper);
  462.       if Default = beYes then
  463.         Ch := 'Y'
  464.       else
  465.         Ch := 'N';
  466.       if QuitAndAll then begin
  467.         CharsToTake := ['Y', 'N', 'A', 'Q'];
  468.         Prompt := Prompt+' (Y/N/A/Q)'
  469.       end
  470.       else
  471.         CharsToTake := ['Y', 'N'];
  472.       ClearPromptLine;
  473.       ReadChar(Prompt, PromptLine, 1, CharsToTake, Ch);
  474.       if GetLastCommand = ccQuit then
  475.         YesNoFunc := beQuit
  476.       else case Ch of
  477.         'Y' : YesNoFunc := beYes;
  478.         'N' : YesNoFunc := beNo;
  479.         'A' : YesNoFunc := beAll;
  480.         'Q' : YesNoFunc := beQuit;
  481.       end;
  482.       ClearPromptLine;
  483.     end;
  484.   end;
  485.  
  486.   function PickFileName(var Mask : PathStr) : Word;
  487.   var
  488.     Dir : DirListPtr;
  489.   begin
  490.     New(Dir, InitCustom(20, 5, 60, 20, BigEdColors, DefWindowOptions or wBordered,
  491.                        MaxAvail, PickVertical, SingleFile));
  492.     if Dir = nil then begin
  493.       PickFileName := InitStatus;
  494.       exit;
  495.     end;
  496.     with Dir^ do begin
  497.       wFrame.AddShadow(shBR, shSeeThru);
  498.       diOptionsOn(diOptimizeSize);
  499.       AddMaskHeader(True, 1, 30, heTC);
  500.       PickFileName := GetFileName(Trim(Mask), AnyFile, Mask);
  501.     end;
  502.     Dispose(Dir, Done);
  503.   end;
  504.  
  505.   function GetFileFunc(MsgCode : Word; Prompt : string;
  506.                        ForceUp, TrimBlanks, Writing, MustExist : Boolean;
  507.                        MaxLen : Byte; DefExt : ExtStr;
  508.                        var S : string) : Boolean;
  509.     {-Get a filename}
  510.   var
  511.     I : Word;
  512.   begin
  513.     GetFileFunc := False;
  514.     if NOT(EditFunc(0, Prompt, ForceUp, TrimBlanks, MaxLen, S)) then
  515.       exit;
  516.     if (Pos('*', S) > 0) or (Pos('?', S) > 0) then begin
  517.       if PickFileName(S) <> 0 then
  518.         exit;
  519.     end;
  520.  
  521.     if Writing then
  522.       if ExistFile(S) then
  523.         GetFileFunc := YesNoFunc(0, 'File exists. Overwrite it?', beNo, False) = beYes
  524.       else
  525.         GetFileFunc := True
  526.     else if (NOT(MustExist)) or (ExistFile(S)) then
  527.       GetFileFunc := True
  528.     else begin
  529.       I := 0;
  530.       ErrorProc(0, I, 'File not found');
  531.     end;
  532.   end;
  533.  
  534. {----------------------------------------------------------------------------}
  535.  
  536.   constructor MyBigEditor.InitCustom(UX, UY, LX, LY : Byte;
  537.                                      var Colors : ColorSet;
  538.                                      WinOpts : LongInt);
  539.   begin
  540.     if not BigEditor.InitCustom(UX, UY, LX, LY, Colors, WinOpts) then Fail;
  541.  
  542.     CompileMode := cmMake;
  543.     CompileType := ctTPC;
  544.   end;
  545.  
  546.   destructor MyBigEditor.Done;
  547.   begin
  548.     BigEditor.Done;
  549.   end;
  550.  
  551.   function MyBigEditor.FindCompileError : Boolean;
  552.   var S, T : String;
  553.       I, N : Integer;
  554.       B : Boolean;
  555.   begin
  556.     B := False;
  557.       {scan the screen, looking for our telltale}
  558.     for I := 1 to ScreenHeight do begin
  559.       FastRead(ScreenWidth, I, 1, S);
  560.       if Pos('): Error', S) > 0 then begin
  561.           {found the telltale}
  562.         B := True;
  563.         Report := S;
  564.  
  565.           {get the file-in-error's name...}
  566.         NFName := Copy(S, 1, Pred(Pos('(', S)));
  567.  
  568.           {...and the line of the error}
  569.         T := Copy(S, Pos('(', S)+1, 5);
  570.         while (Length(T) > 0) and (NOT(T[length(T)] in ['0'..'9'])) do Dec(T[0]);
  571.         if Str2Int(T, LC) then begin
  572.  
  573.             {scan forward, looking for the ^ that indicates the col of the error}
  574.           N := 0;  CC := I;
  575.           while CC <= ScreenHeight do begin
  576.             Inc(CC);
  577.  
  578.               {if N > 0, then error col is past the right screen margin}
  579.             Inc(N);
  580.             FastRead(ScreenWidth, CC, 1, S);
  581.             if Trim(S) = '^' then begin
  582.                 {found the caret, get the col count}
  583.               CC := Pos('^', S) + (80 * Pred(N div 2));
  584.               exit;
  585.             end;
  586.           end;
  587.         end;
  588.       end;
  589.     end;
  590.     FindCompileError := B;
  591.     if NOT B then
  592.       NFName := '';
  593.         {an error report that doesn't contain line/col info, just report it}
  594.       for I := ScreenHeight downto 1 do begin
  595.           {scan from bottom up; first non-blank line is our report}
  596.         FastRead(ScreenWidth, I, 1, Report);
  597.         Report := Trim(Report);
  598.         if Report <> '' then exit;
  599.       end;
  600.   end;
  601.  
  602.   procedure MyBigEditor.FindCompileGood;
  603.   var S : String;
  604.       I : Integer;
  605.   begin
  606.     for I := 1 to ScreenHeight do begin
  607.         {look for our telltale}
  608.       FastRead(ScreenWidth, I, 1, S);
  609.       if Pos(' lines, ', S) > 0 then begin
  610.           {found it}
  611.         Report := S;
  612.         exit;
  613.       end;
  614.     end;
  615.   end;
  616.  
  617.   procedure MyBigEditor.CallCompiler(CType : CompType; CMode : CompMode);
  618.   var
  619.     S, T : PathStr;
  620.     I : Integer;
  621.     L : LongInt;
  622.     F : Boolean;
  623.     B : Boolean;
  624.     CX, CL : Word;
  625.   begin
  626. {$IFDEF UseMouse}
  627.     if (MouseInstalled) then begin
  628.       HideMousePrim(B);
  629. {$IFDEF UseDrag}
  630.       RemoveISRs;
  631. {$ELSE}
  632.       DisableEventHandling;
  633. {$ENDIF}
  634.     end;
  635. {$ENDIF}
  636.  
  637.     S := CompCmds[CType];
  638.     if S = '' then begin
  639.       GotError(epNonFatal+ecStringNotFound, 'No compiler/assembler assigned');
  640.       exit;
  641.     end;
  642.  
  643.     if beOptionsAreOn(beModified) then
  644.       SaveFile;
  645.  
  646.     if not(CType in [ctTPC, ctTPCX, ctTPCW]) then begin
  647.       CMode := cmCustom;
  648.       MainFile := bePathName;
  649.     end;
  650.  
  651.     if CType = ctTD then
  652.       S := S + ' ' + JustName(MainFile)
  653.     else begin
  654.       S := S + ' ' + CompDefOpts[CType]+' ';
  655.       case CMode of
  656.         cmBuild:
  657.           S := S + '/B';
  658.  
  659.         cmErrSrch:
  660.           begin
  661.             T := '';
  662.             if not Edit(0, 'Error address:', True, True, 10, T) then exit;
  663.             S := S + '/F' + T;
  664.           end;
  665.  
  666.         cmCustom:
  667.           begin
  668.             T := '';
  669.             if not Edit(0, 'Options:', True, True, 64, T) then exit;
  670.             S := CompCmds[CType] + ' ' + T;
  671.           end;
  672.       end;
  673.       S := S + ' ' + MainFile;
  674.     end;
  675.  
  676.     TBW^.Draw;
  677.     TBW^.Clear;
  678.     Report := '';
  679.  
  680.       {call the compiler}
  681.     I := ExecDosSwap(S, False, NIL, SwapFilePath);
  682.  
  683.     case CType of
  684.       ctTPC, ctTPCX, ctTPCW :
  685.         begin
  686.           if DOSExitCode <> 0 then begin
  687.             {find the error}
  688.             F := FindCompileError;
  689.  
  690.                 {redraw our editor window}
  691.             if F then begin
  692.               if (NFName <> '') and (NFName <> bePathName) then begin
  693.                   {file-in-error different from our last edit file, so switch}
  694.                   {this restores the new file's state if it's been loaded before}
  695.                 ReadFile(NFName, L);
  696.               end;
  697.                 {jump to the line/col of the error}
  698.               GoToLineCol(LC, CC);
  699.             end;
  700.           end
  701.           else
  702.             {good compile, just redraw the editor and the report}
  703.             FindCompileGood;
  704.         end;
  705.  
  706.       ctTASM:
  707.         if DOSExitCode <> 0 then begin
  708.           if WhereY = ScreenHeight then
  709.             ScrollWindowUp(1, 1, ScreenWidth, ScreenHeight, 1);
  710.           FastWrite(Center('Press a key...', ScreenWidth), ScreenHeight, 1, ColorMono($4F, $70));
  711.           if ReadKeyWord = 0 then ;
  712.         end;
  713.     end;
  714.  
  715.     TBW^.Erase;
  716.     beOptionsOn(beForceRedraw);
  717.     UpdateContents;
  718.  
  719.     GetCursorState(CX, CL);
  720.     DisplayMessage('   '+Report);
  721.     RestoreCursorState(CX, CL);
  722.  
  723. {$IFDEF UseMouse}
  724.     if (MouseInstalled) then begin
  725. {$IFDEF UseDrag}
  726.       InstallISRs;
  727. {$ELSE}
  728.       EnableEventHandling;
  729.       with BigEdColors do
  730.         SoftMouseCursor($0000, (ColorMono(MouseColor, MouseMono) SHL 8) + $04);
  731. {$ENDIF}
  732.       ShowMousePrim(B);
  733.     end;
  734. {$ENDIF}
  735.   end;
  736.  
  737.   procedure MyBigEditor.ShowBackground;
  738.   begin
  739.     TBW^.Draw;
  740.     if ReadKeyWord = 0 then ;
  741.     TBW^.Erase;
  742.   end;
  743.  
  744.   procedure MyBigEditor.SelectCompiler;
  745.   var
  746.     S : ExtStr;
  747.   begin
  748.     S := JustExtension(bePathName);
  749.     S := StUpcase(S);
  750.     if S = 'ASM' then
  751.       CompileType := ctTASM
  752.     else
  753.       CompileType := ctTPC;
  754.   end;
  755.  
  756.   procedure MyBigEditor.DosShell(Cmd : String);
  757.   var
  758.     S : String;
  759.     I : Integer;
  760.     F : Boolean;
  761.     B : Boolean;
  762.   begin
  763. {$IFDEF UseMouse}
  764.     if (MouseInstalled) then begin
  765.       HideMousePrim(B);
  766. {$IFDEF UseDrag}
  767.       RemoveISRs;
  768. {$ELSE}
  769.       DisableEventHandling;
  770. {$ENDIF}
  771.     end;
  772. {$ENDIF}
  773.     S := GetEnv('COMSPEC');
  774.     if Cmd <> '' then
  775.       S := S+' /C '+Cmd;
  776.  
  777.       {draw the background window for the shell}
  778.     TBW^.Draw;
  779.     TBW^.Clear;
  780.     if Cmd = '' then
  781.       WriteLn('DOS Shell - "EXIT" to return to editor.');
  782.  
  783.       {call the shell}
  784.     I := ExecDOSSwap(S, False, NIL, SwapFilePath);
  785.  
  786.     if Cmd <> '' then begin
  787.       if WhereY = ScreenHeight then
  788.         ScrollWindowUp(1, 1, ScreenWidth, ScreenHeight, 1);
  789.       FastWrite(Center('Press a key...', ScreenWidth), ScreenHeight, 1, ColorMono($4F, $70));
  790.       if ReadKeyWord = 0 then ;
  791.     end;
  792.  
  793.     TBW^.Erase;
  794.     beOptionsOn(beForceRedraw);
  795.     UpdateContents;
  796.  
  797. {$IFDEF UseMouse}
  798.     if (MouseInstalled) then begin
  799. {$IFDEF UseDrag}
  800.       InstallISRs;
  801. {$ELSE}
  802.       EnableEventHandling;
  803.       with BigEdColors do
  804.         SoftMouseCursor($0000, (ColorMono(MouseColor, MouseMono) SHL 8) + $04);
  805. {$ENDIF}
  806.       ShowMousePrim(B);
  807.     end;
  808. {$ENDIF}
  809.   end;
  810.  
  811.   procedure MyBigEditor.PerformDosCommand;
  812.   var
  813.     S : String;
  814.   begin
  815.     S := '';
  816.     if NOT(EditFunc(0, 'DOS Cmd:', False, True, 132, S)) then exit;
  817.     DOSShell(S);
  818.   end;
  819.  
  820.   procedure MyBigEditor.ExecuteSelf;
  821.   var
  822.     S : String;
  823.   begin
  824.     S := ForceExtension(bePathName, 'EXE');
  825.     DOSShell(S);
  826.   end;
  827.  
  828.   procedure MyBigEditor.SaveState(var S);
  829.   begin
  830.     with SpcStateRec(S) do begin
  831.       BigEditor.SaveState(SSR);
  832.       CT := CompileType;
  833.     end;
  834.   end;
  835.  
  836.   procedure MyBigEditor.RestoreState(var S);
  837.   begin
  838.     with SpcStateRec(S) do begin
  839.       BigEditor.RestoreState(SSR);
  840.       CompileType := CT;
  841.     end;
  842.   end;
  843.  
  844.   procedure MyBigEditor.ReadFile(FName : string; var FSize : LongInt);
  845.   var
  846.     P : FileNodePtr;
  847.     S : SpcStateRec;
  848.   begin
  849.     DisplayMessage('Reading...');
  850.     FName := DefaultExtension(FName, beDefExt);
  851.     FName := FExpand(FName);
  852.     BigEditor.ReadFile(FName, FSize);
  853.     P := FindFileInList(FName);
  854.     if P <> nil then
  855.       RestoreState(P^.State)
  856.     else begin
  857.       SelectCompiler;
  858.       SaveState(S);
  859.       AddFileToList(FName, S);
  860.     end;
  861.     ClearPromptLine;
  862.   end;
  863.  
  864.   procedure MyBigEditor.SaveFile;
  865.   var
  866.     S : SpcStateRec;
  867.   begin
  868.     DisplayMessage('Saving...');
  869.     BigEditor.SaveFile;
  870.     SaveState(S);
  871.     AddFileToList(bePathName, S);
  872.     ClearPromptLine;
  873.   end;
  874.  
  875.   procedure MyBigEditor.NewFilePrompted;
  876.   var
  877.     S : SpcStateRec;
  878.   begin
  879.     SaveState(S);
  880.     AddFileToList(bePathName, S);
  881.     BigEditor.NewFilePrompted;
  882.     MainFile := bePathName;
  883.   end;
  884.  
  885.   procedure Abort(S : String);
  886.   begin
  887.     WriteLn('Fatal: '+S);
  888.     Halt(1);
  889.   end;
  890.  
  891.   function InitEdWin(var Ed : MyBigEditorPtr; IsNewFile : Boolean; var FN : PathStr) : Word;
  892.   var
  893.     FS : LongInt;
  894.     W : Word;
  895.   begin
  896.     New(Ed, InitCustom(1, 3, ScreenWidth, ScreenHeight, BigEdColors,
  897.                        DefWindowOptions));
  898.     if Ed = nil then begin
  899.       InitEdWin := InitStatus;
  900.       exit;
  901.     end;
  902.  
  903.     with Ed^ do begin
  904.       AdjustFrameCoords(1, 1, ScreenWidth, ScreenHeight);
  905.       SetStatusProc(Status);
  906.       SetEditProc(EditFunc);
  907.       SetYesNoProc(YesNoFunc);
  908.       SetGetFileProc(GetFileFunc);
  909.       SetErrorProc(ErrorProc);
  910.       SetDefaultExtension('PAS');
  911.  
  912.       W := RawError;
  913.       InitEdWin := W;
  914.       if W <> 0 then exit;
  915.  
  916.       if IsNewFile then begin
  917.         if (FN = '') or (HasWildCards(FN)) then begin
  918.           if not GetFile(0, 'File name:', True, True, False, False, 80, beDefExt, FN) then begin
  919.             Dispose(Ed, Done);
  920.             Ed := nil;
  921.             InitEdWin := $FFFF;
  922.             exit;
  923.           end;
  924.         end;
  925.  
  926.         if FN <> '' then
  927.           FN := DefaultExtension(FN, beDefExt);
  928.         ReadFile(FN, FS);
  929.         if cwGetLastError <> 0 then begin
  930.           InitEdWin := cwGetLastError;
  931.           Dispose(Ed, Done);
  932.           Ed := nil;
  933.           exit;
  934.         end;
  935.  
  936.         MainFile := bePathName;
  937.         FN := '*.PAS';
  938.       end;
  939.     end;
  940.   end;
  941.  
  942.   procedure InitSystem;
  943.   var
  944.     MX : Byte;
  945.   begin
  946.     if OpDos.DosVersion < $0300 then
  947.       Abort('This program requires DOS version 3.0 or higher.');
  948.  
  949.     FilesList.Init;
  950.  
  951.     New(TBW, Init(1, 1, ScreenWidth, ScreenHeight));
  952.     if TBW = nil then
  953.       Abort('Error '+Long2Str(InitStatus mod 10000)+' initializing screen management');
  954.  
  955. {$IFDEF UseMouse}
  956.     if (MouseInstalled) then begin
  957. {$IFDEF UseDrag}
  958.       with BigEdColors do
  959.         MX := ColorMono(MouseColor, MouseMono);
  960.       BigEditorCommands.SetMouseCursor((MX shl 8) + NormMouse,
  961.                                        (MX shl 8) + MoveMouse,
  962.                                        (MX shl 8) + ResizeMouse);
  963. {$ELSE}
  964.       EnableEventHandling;
  965.       with BigEdColors do
  966.         SoftMouseCursor($0000, (ColorMono(MouseColor, MouseMono) SHL 8) + NormMouse);
  967.       BigEditorCommands.cpOptionsOn(cpEnableMouse);
  968. {$ENDIF}
  969.   end;
  970. {$ENDIF}
  971.  
  972.     with BigEditorCommands do begin
  973.       SetUserHookProc(UserHook);
  974.       AddCommand(ccAbandonFile, 1, AltX, 0);
  975.       AddCommand(ccUser1, 1, AltS,   0);  {Dos Shell}
  976.       AddCommand(ccUser2, 1, F9,     0);  {Make}
  977.       AddCommand(ccUser3, 1, AltF9,  0);  {Build}
  978.       AddCommand(ccUser4, 1, CtrlF9, 0);  {Find error}
  979.       AddCommand(ccUser5, 1, ShF9,   0);  {Custom}
  980.       AddCommand(ccUser6, 1, AltF8,  0);  {Toggle compiler type}
  981.       AddCommand(ccUser7, 1, F8,     0);  {debug}
  982.       AddCommand(ccUser8, 1, AltF10, 0);  {show compile screen}
  983.     end;
  984.     ClrScr;
  985.   end;
  986.  
  987.   procedure Main;
  988.   var
  989.     W : Word;
  990.     FN : PathStr;
  991.     Fin : Boolean;
  992.   begin
  993.     InitSystem;
  994.  
  995.     if ParamCount = 0 then
  996.       FN := '*.PAS'
  997.     else
  998.       FN := ParamStr(1);
  999.  
  1000.     W := InitEdWin(BE, True, FN);
  1001.     if W <> 0 then
  1002.       Abort('Error '+Long2Str(W mod 10000)+' initializing Editor');
  1003.  
  1004.     with BE^ do begin
  1005.       Draw;
  1006.       ClearPromptLine;
  1007.  
  1008.       Fin := False;
  1009.       repeat
  1010.         Process;
  1011.         case GetLastCommand of
  1012.           ccUser1:
  1013.             PerformDosCommand;
  1014.  
  1015.           ccUser2:
  1016.             CallCompiler(CompileType, cmMake);
  1017.  
  1018.           ccUser3:
  1019.             CallCompiler(CompileType, cmBuild);
  1020.  
  1021.           ccUser4:
  1022.             CallCompiler(CompileType, cmErrSrch);
  1023.  
  1024.           ccUser5:
  1025.             CallCompiler(CompileType, cmCustom);
  1026.  
  1027.           ccUser6:
  1028.             if CompileType = ctTASM then
  1029.               CompileType := ctTPC
  1030.             else
  1031.               Inc(CompileType);
  1032.  
  1033.           ccUser7:
  1034.             CallCompiler(ctTD, cmCustom);
  1035.  
  1036.           ccUser8:
  1037.             ShowBackground;
  1038.  
  1039.           ccSaveExit,
  1040.           ccQuit,
  1041.           ccAbandonFile:
  1042.             begin
  1043.               if beOptionsAreOn(beModified) then
  1044.                 if YesNo(0, emFileModified, beYes, False) = beYes then
  1045.                   SaveFile;
  1046.               DisplayMessage('Working...');
  1047.               LList^.Clean;
  1048.               DisplayMessage('');
  1049.               Fin := True;
  1050.             end;
  1051.  
  1052.           else
  1053.             Fin := True;
  1054.         end;
  1055.       until Fin;
  1056.       Erase;
  1057.     end;
  1058.  
  1059.     Dispose(BE, Done);
  1060.     Dispose(TBW,Done);
  1061.     FilesList.Done;
  1062.     ClrScr;
  1063.   end;
  1064.  
  1065. end.
  1066.  
  1067.